
requirejs.config({
    baseUrl: '/js',
});

var stats, render, camera, scene, clock;
//doll.js requires signals, jquery, and tween to function
requirejs(['lib/signals.min', 'lib/jquery.min', 'lib/tween.min', 'engine/doll', 'engine/ui', 'engine/ui/selectable',
           'engine/draw', 'engine/fetch', 'engine/audio', 'engine/input', 'engine/cam',
          'engine/text', 'engine/voxel', 'engine/isosurface', 'engine/perlin',
          'engine/user', 'engine/world', 'engine/entity'],
          function(signals) {
              //I barely know how I got this but it works
              //console.log = function () {};
              doll.signals = signals;
              init();
              add_info();
              setup_audio();
              fill_scene();
              add_stats();
              animate();
         });

var thing, chunk, snobj, wireobj, iso,ball, ball2, ball2_anim, ball3, ball3_anim;
var world, moon, user, user_cursor;
function fill_scene() {

    //lights
    var light = new THREE.SpotLight(0xffffff);
    light.position.set(1000,1000,1000);
    scene.add(light);
    light = new THREE.SpotLight(0xffffff);
    light.position.set(-1000,-1000,-1000);
    scene.add(light);

    world = new doll.world(
        {
            scene: scene, 
            camera: camera
        });

    ball = new THREE.Mesh(
        new THREE.SphereGeometry(20,20,20),
        new THREE.MeshBasicMaterial({color:0xffeee3}));

    ball.position.set(0,100,0);
    world.add_mesh(ball);

    ball2 = new THREE.Mesh(
        new THREE.SphereGeometry(20,20,20),
        new THREE.MeshBasicMaterial({color:0xff00ee}));

    ball2_anim = doll.orbit_anim(ball.position, 75, 0, 90 * doll.RAD, 0.05, 0.08);

    world.add_mesh(ball2);

    ball3 = new THREE.Mesh(
        new THREE.SphereGeometry(20,20,20),
        new THREE.MeshBasicMaterial({color:0xff2233}));

    ball3_anim = doll.orbit_anim(ball2.position, 75, 0, 90 * doll.RAD, 0.01, 0);
    world.add_mesh(ball3);

    user = new doll.user.flight();
    user.build_mesh();
    world.connect(user);

    scene.add(doll.debug_grid());
    camera.position.set(0, 500, 900);

    world.camera.set_mode(world.camera.FLIGHT_CAM);
    world.camera.flight.user = user;
    world.scene.add(user.cursor);
}

function add_stats() {
    stats = new Stats();
    stats.setMode(0); // 0: fps, 1: ms

    // Align top-left
    stats.domElement.style.position = 'absolute';
    stats.domElement.style.left = '0px';
    stats.domElement.style.top = '0px';
    document.body.appendChild( stats.domElement );
}

var container
function add_info() {
    container = document.createElement( 'div' );
    document.body.appendChild( container );
    
    var info = document.createElement( 'div' );
    info.style.position = 'absolute';
    info.style.top = '10px';
    info.style.width = '100%';
    info.style.textAlign = 'center';
    info.innerHTML = 'doll.js Flight test <br><strong> click to activate pointerlock </strong>';
    container.appendChild( info );
}

function init() {
    clock = new THREE.Clock();
    scene = new THREE.Scene();
    camera = new doll.cam( 45, window.innerWidth / window.innerHeight, 1, 10000 );
    camera.position.set(0, 0, 0);
    render = new THREE.WebGLRenderer( {antialias: true} );
    render.setSize( window.innerWidth, window.innerHeight );

    var $view = $('#doll_view');
    $view.append(render.domElement);
    $('canvas').attr('id', '3d_canvas');
    doll.view = $view;
    //document.body.appendChild( render.domElement );

    //config engine
    //should be done with config function in the future
    doll.window = window;
    doll.document = document;
    doll.render = render;
    doll.stats = stats;
    doll.camera = camera;//current camera global
    doll.scene = scene; //current scene global
    doll.window_width = window.innerWidth;
    doll.window_height = window.innerHeight;
    doll.halfwidth = doll.window_width * 0.5;
    doll.halfheight = doll.window_height * 0.5;

    //init modules order matters will write a nice
    doll.init();
    doll.voxel.init();

    doll.input.on_mousedown(function(mouse) {
            if(doll.input.pointerlocked && mouse.button == 1 && !user) {

            } else if (doll.input.pointerlocked && mouse.button == 3 && user) {

            }
    });

    doll.input.on_mouseenter(function(mouse) {
        console.log('Enter', mouse);
    });

    doll.input.on_mouseleave(function(mouse) {
        console.log('Leave', mouse);
    });

    //activate user controls
    camera.control();
}

function setup_audio() {
    //loads from assets/audio
    var audio = [
//        'ponponpon.wav',
//        'oniichan_09.ogg',
        'piano_sheet01.ogg'
    ];
    doll.audio.complete = function() {
        console.log('hey I got all my audio');
        //doll.audio.play(0);
    }
    doll.audio.fetch(audio, false);
}

var sample = 0.0;
function animate() {
    doll.fps(60); //lock fps at 60
    doll.tick = (new Date).getTime();

    doll.run = function() {
        var curTime = (new Date).getTime();
        if( curTime < doll.tick) {
            //its not time to step so just render as often as possible
            render.render(scene, camera);
            //doll.voxel.update();//maybe do it while no animations
            //are being calculated?
            requestAnimationFrame(doll.run, render.domElement);
            return;
        }

        //TODO: prevent massive frame jumps when user leaves here

        stats.begin();
        //var delta = clock.getDelta();
        var delta = doll.FPS / 1000.0;//convert from ms to seconds passed

        //set up a frame
        //world updates game so all the entities and whatnot
        world.update(delta);

        ball2.position = ball2_anim.step();
        ball3.position = ball3_anim.step();

        //update all subsystems
        //may want to update some subsystems more often than others
        doll.input.update(delta);
        doll.ui.animate(delta);
        render.render(world.scene, world.camera);

        world.finalize(delta);

        stats.end();
        //next step happens at a fixed time to smooth out the animations
        doll.tick += doll.FPS;
        requestAnimationFrame(doll.run, render.domElement);
    };

    doll.run();
}



